package com.javabasic.algorithm.leetcode;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author xiongmin
 * @Description //TODO
 * @Date 2020/8/12 18:15
 * @Version 1.0
 **/
public class PrintFooBarAlternately {

}


class FooBar {
    private int n;
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private volatile boolean flag = true;

    public FooBar(int n) {
        this.n = n;
    }

    public void foo(Runnable printFoo) throws InterruptedException {
        lock.lock();
        try {
            for (int i = 0; i < n; i++) {
                while (!flag) {
                    condition1.await();
                }
                // printFoo.run() outputs "foo". Do not change or remove this line.
                printFoo.run();
                flag = false;
                condition2.signal();
            }
        } finally {
            lock.unlock();
        }


    }

    public void bar(Runnable printBar) throws InterruptedException {

        lock.lock();
        try {
            for (int i = 0; i < n; i++) {
                while (flag) {
                    condition2.await();
                }
                // printBar.run() outputs "bar". Do not change or remove this line.
                printBar.run();
                flag = true;
                condition1.signal();
            }
        } finally {
            lock.unlock();
        }

    }
}
